import initPuppeteerPool from './generic-pool'
// import { getPuppetterExecutablePath } from '../lib/helper'

const defaultBorwserConfig = {
    // 以 无头模式（隐藏浏览器界面）运行浏览器
    headless: true,
    // 设置该参数能解决网站证书无效问题
    ignoreHTTPSErrors: true,
    // 采用了配置方式配置
    // executablePath: getPuppetterExecutablePath(),
    // 不使用 websocket
    pipe: true,
    args: [
        '--disable-gpu', // GPU硬件加速
        '--disable-dev-shm-usage', // 创建临时文件共享内存
        '--disable-setuid-sandbox', // uid沙盒
        '--no-first-run', // 没有设置首页。在启动的时候，就会打开一个空白页面。
        '--no-sandbox', // 沙盒模式
        '--no-zygote',
        '--single-process', // 单进程运行
    ],
}
const puppeteerPool = initPuppeteerPool({
    puppeteerArgs: defaultBorwserConfig
})

class Poppeteer {
    /**
     * 截图
     * @param {
     * url string 请求地址
     * width string 视口宽度
     * height string 视口高度
     * waitTimeout number 等待渲染超时时间
     * selector string 选择器、类和id
     * headers Record<string, string> 设置header键值对
     * } param0 
     * @returns 
     */
    async screenshot({
        url,
        width = 375,
        height = 677,
        waitTimeout = 5000,
        selector,
        encoding,
        headers
    }) {
        let page = null
        try {
            return await puppeteerPool.use(async browser => {
                page = await browser.newPage()
                await page.setViewport({ width, height });
                headers && (await page.setExtraHTTPHeaders(headers));
                await page.goto(url, {
                    // 不再有网络连接时触发（至少500毫秒后）,认为页面跳转完成
                    waitUtil: 'networkidle0',
                });
                // 加载等待页面加载完成
                await this._waitRender(page, waitTimeout)

                const img = await this._screenshot({ page, selector, encoding })
                return img
            })
        } catch (e) {
            this._error('裁剪图片错误信息', e)
            return `error，${e.message}`
        } finally {
            page && await page.close()
        }
    }

    async _screenshot({ page, selector, encoding }) {
        let shotPage = page
        let config = { type: 'png' }
        if (encoding) {
            config.encoding = encoding
        }
        if (selector) {
            const element = await page.$(selector)
            if (element) {
                shotPage = element
                const boundingBox = await element.boundingBox();
                config.clip = boundingBox
            }
        } else {
            config.fullPage = true
        }
        const img = await shotPage.screenshot(config)
        return img
    }

    async _waitRender(page, timeout) {
        const renderDoneHandle = await page.waitForFunction('window._puppeteerRenderDone', {
            polling: 120,
            timeout: timeout,
        });

        const renderDone = await renderDoneHandle.jsonValue();
        if (renderDone === true) return true;
        this._info('_waitRender渲染失败')
    }

    _info(...args) {
        console.info('[Puppeteer info]  ——————  ', ...args)
    }

    _error(...args) {
        console.error('[Puppeteer error]    ——————  ', ...args)
    }

    static getInstance() {
        return Poppeteer.instance || (Poppeteer.instance = new Poppeteer())
    }
}

module.exports = Poppeteer